/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package models;

import entities.Movie;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author Vladimír
 */
public class MovieTableModel extends AbstractTableModel{

    private List<Movie> movies = new ArrayList<>(); 
    
    @Override
    public int getRowCount() {
        return movies.size();
    }

    @Override
    public int getColumnCount() {
        return 9;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Movie movie = movies.get(rowIndex);
    String tmp;
    switch (columnIndex) {
            case 0:
                if (movie.getMedium() == null){
                    return "none";
                } else {
                    return movie.getMedium().getTitle();
                }
            case 1:
                return movie.getTitle();
            case 2:
                return movie.getReleaseYear();
            case 3:
                tmp = movie.getCountriesOfOrigin().toString();
                return tmp.substring(tmp.indexOf('[')+1,tmp.lastIndexOf(']'));
            case 4:
                return timeToString(movie.getRunTime());
            case 5:
                tmp = movie.getCast().toString();
                return tmp.substring(tmp.indexOf('[')+1,tmp.lastIndexOf(']'));
            case 6: 
                tmp = movie.getDirectors().toString();
                return tmp.substring(tmp.indexOf('[')+1,tmp.lastIndexOf(']'));
            case 7:
                tmp = movie.getGenres().toString();
                return tmp.substring(tmp.indexOf('[')+1,tmp.lastIndexOf(']'));
            case 8: 
                return movie.getNote();
            default:
                throw new IllegalArgumentException("Records table model doesn't support " + (columnIndex + 1) + " collumns");
        }
    }
    
    @Override
    public String getColumnName(int column){
        switch (column) {
            case 0:
                return "Medium";
            case 1:
                return "Title";
            case 2:
                return "Published";
            case 3:
                return "Contries of origin";
            case 4:
                return "Run time";
            case 5:
                return "Cast";
            case 6: 
                return "Directors";
            case 7:
                return "Genres";
            case 8: 
                return "Note";
            default:
                throw new IllegalArgumentException("Records table model doesn't support " + (column + 1) + " collumns");
        }
    }
    
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case 0:
            case 1:
                return String.class;
            case 2:
                return Integer.class;
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
            case 8: 
                return String.class;
            default:
                throw new IllegalArgumentException("Records table model doesn't support " + (columnIndex + 1) + " collumns");
        }
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return (columnIndex!=3)&&(columnIndex!=7)&&(columnIndex!=0);
    }

    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        Movie movie = movies.get(rowIndex);
        
        if (value == null)
            return;

        switch (columnIndex) {
            case 1:
                if (((String)value).isEmpty())  
                    return;
                movie.setTitle((String) value);
                break;
            case 2:
                if (((Integer)value) < 1000 || ((Integer)value)>9999) 
                    return;
                movie.setReleaseYear((Integer) value);
                break;
            case 4:
                Integer time = stringToTime((String)value);
                if(time==null||time<0)
                    return;
                movie.setRunTime(time);
                break;
            case 5:
                movie.setCast(parseString((String)value));
                break;
            case 6:
                movie.setDirectors(parseString((String)value));
                break;
            case 8:
                movie.setNote(((String) value).length() > 250 ? ((String) value).substring(0, 249) : (String) value);
                break;
            default:
                throw new IllegalArgumentException();
        }

        fireTableCellUpdated(rowIndex, columnIndex);

    }

    public Movie getMovieAt(int i) {
        return movies.get(i);
    }
    
    public void addMovies(List<Movie> allRecords) {
        movies.clear();
        movies.addAll(allRecords);
        fireTableDataChanged();
    }

    public void addMovie(Movie movie) {
        movies.add(movie);
        fireTableDataChanged();
    }
    
    public void removeMovie(Movie movie) {
        movies.remove(movie);
        fireTableDataChanged();
    }
    
    public void removeMovies(List<Movie> moviesToRemove) {
        movies.removeAll(moviesToRemove);
        fireTableDataChanged();
    }
   
    public static List<String> parseString(String s)
    {
        List<String> out = new ArrayList<>();
        String[] values =s.split(", ");
        for(String value : values)
        {
            if(!value.isEmpty())
                out.add(value);
        }
        return out;
    }
    
    public static Integer stringToTime(String s)
    {
        if(s==null||s.isEmpty())
            return null;
        int time=0;
        int tmp;
        String[] parsed = s.split(":");
        if(parsed.length<1||parsed.length>2)
            return -1;
        for(int i=0;i<parsed.length;i++)
        {
            try{
                tmp = (int) (Integer.parseInt(parsed[i])*(Math.pow(60,(parsed.length-1)-i)));
                if(tmp<0)
                    return -1;
                time+=tmp;
            }catch(NumberFormatException e){
                return -1;
            }
        } 
        return time;
    }
    
    public static String timeToString(int time)
    {
        int hours;
        int minutes;
        
        hours=time/60;
        minutes=(time-60*hours);
        
        return hours + ":" + minutes ;
    }

    
    
}
